home *** CD-ROM | disk | FTP | other *** search
- REVLVL equ 5 ;Revision level 6-25-85
-
- ;=============================================================================
- ;
- ; MSYTIPRO.ASM This file contains system dependent terminal emulation routines
- ; for the H19 and Tektronix 4010 terminals.
- ;
- ; NOTE: ESC Z and ANSI mode don't work.
- ;
- ; Credits: Dan Smith Computing Center (303) 273-3396
- ; Colorado School of Mines
- ; Golden, Colorado 80241
- ; Joe Smith, now at TYMSHARE, 39100 Liberty St, Fremont CA 94538
- ;
- ;
- ; The following H19 escape codes are supported:
- ;
- ; Esc H Cursor home Esc L Insert line
- ; Esc C Cursor forward Esc M Delete line
- ; Esc D Cursor backward Esc N Delete character
- ; Esc B Cursor down Esc O Exit insert mode
- ; Esc A Cursor up Esc @ Enter insert mode
- ; Esc I Reverse index Esc p Enter reverse video mode
- ; Esc Y Direct cursor addressing Esc q Exit reverse video mode
- ; Esc E Clear display Esc j Save cursor position
- ; Esc J Erase to end of page Esc k Restore cursor position
- ; Esc K Erase to end of line
- ; Esc x4 Set block cursor Esc Z Identify as VT52
- ; Esc y4 Set underscore cursor
- ;
- ; The following H19 codes are not supported:
- ;
- ; Esc n Cursor position report Esc < Enter ANSI mode
- ; Esc b Erase beginning of display Esc [ Enter hold screen mode
- ; Esc l Erase entire line Esc \ Exit hold screen mode
- ; Esc o Erase beginning of line Esc F Enter graphics mode
- ; Esc z Reset to power up config. Esc G Exit graphics mode
- ; Esc r ? Modify baud rate Esc t Enter keypad shifted mode
- ; Esc x 1-3 Set modes 1 through 3 Esc u Exit keypad shifted mode
- ; Esc x 5-9 Set modes 5 through 9 Esc = Enter alt keypad mode
- ; Esc y 1-3 Reset modes 1 through 3 Esc > Exit alt keypad mode
- ; Esc y 5-9 Reset modes 5 through 9 Esc } Keyboard disable
- ; Esc v Wrap around at end of line Esc { Keyboard enable
- ; Esc w Discard at end of line Esc ] Transmit 25th line
- ; Esc Z Identify as H-19 Esc # transmit page
- ;
- ;=============================================================================
-
- include mssdef.h
-
- datas segment public 'datas'
- extrn flags:byte
-
- tekflag db 0 ;Flag for ESCape sequences
- visible db 0 ;0 to move, 1 to draw a line
- tek_hiy dw 0 ;Y coordinate in Tektronix mode
- tek_loy db 0
- tek_hix dw 0
- tek_lox db 0
- tek_lsb db 0 ; Low-order 2 bits of X + low Y (4014 mode)
-
- arrtab db 48h,'A' ;Up arrow
- db 50h,'B' ;Down arrow
- db 4bh,'D' ;Left arrow
- db 4dh,'C' ;Right arrow
- arrtabl equ ($-arrtab) / 2 ;Number of keys in arrtab
-
- spctab db 27,13,10,08,09,07,29,12
- lspctab equ $-spctab
- spcjmp dw outesc,outcr,outlf,outbs,outtab,beep,tekini,ffeed
-
- esctab db 'YABCDEHIJKLMNO@pqjkxy' ;Recognized escape codes
- db 'Z',12,1ah
- lesctab equ $-esctab
- escjmp dw movcur,curup,curdwn,currt ;Escape code routines. This
- dw outbs,clrscr,curhom,revind ;array must parallel the codes
- dw clreow,clreol,inslin,dellin ;listed above.
- dw delchr,noins,entins,invvid
- dw nrmvid,savecur,restcur,setm,resetm
- dw sendid,escff,xhair
-
- argadr dw 0
- escchar db 0
- videobuf dw 0de00h
- ttstate dw 0
- wcoord db 0
- savrow db 0
- insmod db 0
- cursor dw 0
- oldcur dw 0
-
- xmult dw 9 ;Scale TEK to TI by 9/13
- xdiv dw 13 ;so that 0-1023 converts to 0-708
- ymult dw 5 ;Scale TEK to TI by 5/13
- ydiv dw 13 ;so that 0-779 converts to 299-0
- ybot dw 299 ;Bottom of screen is Y=299
- oldx dw 0 ;Previous scaled coordinates
- oldy dw 0
- grseg dw 0
-
- datas ends
-
- code segment public
- assume cs:code,ds:datas
-
- extrn beep:near, prtchr:near, outchr:near
- public term
-
- ;=============================================================================
- ; Main entry point for Tektronix 4010 - Heathkit H19 terminal emulation.
- ;=============================================================================
- db 'term'
- term proc near
- mov argadr,ax ;Save address of argument block
- call termini
- term10: call inport ;Input from modem
- jnc term20 ;No input available; Check keyboard
- call outtty ;Print on terminal
- term20: mov ah,1 ;See if a character has been typed
- int 4ah ; on keyboard
- jz term10 ;Jump if not
- xor ah,ah ;Read char from keyboard buffer
- int 4ah
- cmp al,escchar ;See if the Esc character (^])
- jz term30 ;Jump if it is
- call outport ;Send character out comm port
- jmp short term20 ;Make sure KB buffer doesnt overrun
- term30: call termend
- ret
- term endp
-
- ;=============================================================================
- ; TERMINI Subroutine to initialize the terminal before starting emulation
- ;=============================================================================
- termini proc near
- mov bx,argadr ;Save escape char in local storage
- mov al,[bx].escc
- mov escchar,al
- mov grseg,0d000h ;Assume green on a 3 plane system
- int 4fh ;Get system configuration
- test ax,4000h ;See if graphics plane 3 exists
- jnz ti10 ;Jump if it does
- mov grseg,0c000h ;Reset to plane 1 for a 1 plane system
- ti10: mov ttstate,offset nstate
- mov insmod,0 ;Turn off insert mode
- mov ah,13h ;Necessary to clear screen in order to
- int 49h ; get CRTC start address in sync with
- mov word ptr cursor,0 ; cursor position for direct video
- ret ; buffer access.
- termini endp
-
- ;=============================================================================
- ; TERMEND Subroutine to clean up after terminal emulation.
- ;=============================================================================
- termend proc near
- ;*; mov ah,13h ;Clear text screen
- ;*; int 49h
- ;*; mov ah,14h ;Clear graphics screen
- ;*; int 49h
- ret
- termend endp
-
- ;=============================================================================
- ; Routine to input a character from the modem port. If no character available
- ; this returns with the carry flag cleared. (NC)
- ;=============================================================================
- inport proc near ;Input from the modem
- call prtchr
- jmp short ip10 ;Character available
- nop ;Need 3 bytes
- clc ;Indicate no character
- ret
- ip10: and al,7fh ;No parity here for terminal emulation
- stc ;Indicate character available
- ret
- inport endp
-
- ;=============================================================================
- ; Subroutine to translate and send the character out the communication port
- ;=============================================================================
- outport proc near
- cmp flags.vtflg,1
- jne op2 ;Jump if no Heath-19 emulation
- or al,al
- jz op5 ;Jump if a special key
- op2: mov ah,al
- jmp short op30
- op5: mov cx,arrtabl ;Number of entries in translation table
- mov si,offset arrtab ;Point to start of translation table
- op10: cmp ah,[si]
- jz op20 ;Jump if found key
- add si,2 ;Point to next key scan code
- loop op10
- ret ;Scan code not found; don't send it
- op20: mov ah,27
- call outchr ;Send a leading escape char
- nop ;Waste 3 bytes to ignore error
- nop
- nop
- mov ah,[si+1] ;Get translated code value
- op30: call outchr ;Output character in AH
- nop ;Waste 3 bytes to ignore error
- nop
- nop
- ret
- outport endp
-
- ;=============================================================================
- ; Subroutine to send the character in AL to the screen. If Heath-19 emulation
- ; is on, the character will be interpreted according to H-19 and Tektronix 4010
- ; escape codes.
- ;=============================================================================
- outtty proc near
- cmp flags.vtflg,1
- jne otty10 ;Jump if no Heath-19 emulation
- mov dx,cursor ;These may need cursor...
- cld ;Set here so its not required later
- jmp ttstate ;Jump according to current state
- otty10: mov dl,al ;Print char in al at cursor position
- mov ah,2 ; using DOS
- int 21h
- ret
- outtty endp
-
- ;=============================================================================
- ; Subroutine to process the character in AL according to the normal state
- ;=============================================================================
- nstate proc near
- cmp al,32 ;Special character?
- jb conchar ;Yes, perform control char operation
- cmp insmod,0 ;In insert mode?
- je ns10 ;No, output normal
- push ax ;Save character
- call inschr ;Insert a blank in line
- pop ax ;Restore character
- ns10: jmp pchar ;Print char in AL
- nstate endp
-
- ;=============================================================================
- ; Subroutine to handle the ASCII character below 32 in al
- ;=============================================================================
- conchar proc near
- mov di,offset spctab ;See if character is in table
- mov cx,lspctab
- repne scasb
- jz cc10 ;Go process if it was
- push ax ;Save char
- mov al,'^'
- call pchar ;Print caret
- pop ax
- add al,'A'-1 ;Make control character printable
- jmp pchar ;Print, then return
- cc10: sub di,offset spctab+1 ;Get index of char
- shl di,1 ;Double for word offset
- jmp spcjmp[di] ;And go handle
- conchar endp
-
- ;=============================================================================
- ; special char routines. cursor is in dx, char in al
- ;=============================================================================
- outlf proc near
- inc dl ;Bump row
- jmp setcur
- outlf endp
-
- outcr proc near
- xor dh,dh ;Set col to 0
- jmp setcur
- outcr endp
-
- outbs proc near
- or dh,dh
- jle setcur ;Col 0, can't back up
- dec dh ;Back up col
- jmp setcur ;And use if reasonable
- outbs endp
-
- outtab proc near
- add dh,8 ;Tab is at most 8 columns
- and dh,not 111b ;Round down to a multiple of 8
- cmp dh,80 ;Out of range?
- jb outta1 ;No, go set it
- mov dh,80-1 ;Else just move to right margin
- outta1: jmp setcur
- outtab endp
-
- outesc proc near
- mov ttstate,offset estate ;Expect escape sequence.
- ret
- outesc endp
-
- ;=============================================================================
- ; Escape-char handling routines
- ;=============================================================================
- estate proc near
- mov ttstate,offset nstate ;Put state back to normal
- mov di,offset esctab ;Escape char tbl
- mov cx,lesctab ;Length of tbl
- repne scasb ;Look for it in tbl
- jz es10 ;Found, go use it
- push ax
- mov al,27 ;Output Esc character
- call pchar
- pop ax ;Output unrecognized escape code
- jmp pchar
- es10: sub di,offset esctab+1 ;Get offset into tbl
- shl di,1 ;Convert to word offset
- jmp escjmp[di] ;And go dispatch on it
- estate endp
-
- ;=============================================================================
- ; Subroutine to print a character at the current cursor position and advance
- ; the cursor to the next position.
- ;=============================================================================
- pchar proc near
- push es ;Save ES
- push ax ;Save char to print
- mov dx,cursor ;Get row and column
- call scrloc ;Map DX to ES:DI
- pop ax ;Restore char to print
- stosb ;Put into video buffer
- pop es ;Restore segment
- inc dh ;Bump col
- jmp setcur ;Position cursor
- pchar endp
-
- ;=============================================================================
- ; Subroutine to position the cursor. This routine will wrap lines and scroll
- ; the screen. The row is in DL, the column is in DH
- ;=============================================================================
- setcur proc near
- cmp dh,80 ;See if in range
- jae sc20
- cmp dl,24 ;Lines go from 0 to 23
- jbe sc10 ;Not off end, keep going
- push dx ;Save row/col
- xor dx,dx
- call dellin ;Scroll up one line by deleting top line
- pop dx
- mov dl,24 ;Go to bottom line again...
- sc10: mov cursor,dx ;Save cursor pos
- mov ah,2
- int 49h ;Set cursor
- sc20: ret
- setcur endp
-
- ;=============================================================================
- ; Subroutine to move the cursor up and possibly scroll the screen down
- ;=============================================================================
- revind proc near
- cmp dl,0
- jle rev10
- dec dl ;back up a row
- jmp setcur ;and go set cursor
- rev10: xor dx,dx
- jmp inslin ;Insert a line at top of screen
- revind endp
-
- ;=============================================================================
- ; Subroutine to move the cursor up
- ;=============================================================================
- curup proc near
- cmp dl,0 ;w/in range?
- jle curu10 ;no, skip this
- dec dl ;else back up
- curu10: jmp setcur ;and go set position
- curup endp
-
- ;=============================================================================
- ; Subroutine to move the cursor down
- ;=============================================================================
- curdwn proc near
- inc dl
- jmp setcur ;increment row (setcur can scroll!)
- curdwn endp
-
- ;=============================================================================
- ; Subroutine to move the cursor 1 position to the right.
- ;=============================================================================
- currt proc near
- inc dh
- jmp setcur
- currt endp
-
- ;=============================================================================
- ; Subroutine to home cursor and clear screen
- ;=============================================================================
- clrscr proc near
- call curhom ;go home cursor
- mov dx,cursor
- jmp clreow ;then clear to end of window
- clrscr endp
-
- ;=============================================================================
- ; Subroutine to home the cursor
- ;=============================================================================
- curhom proc near
- xor dx,dx ;move to 0,0
- jmp setcur
- curhom endp
-
- ;=============================================================================
- ; Subroutine to clear the screen from the cursor to the end of the window
- ;=============================================================================
- clreow proc near
- push es
- call scrloc ;Map DX into ES:DI in the video buffer
- mov cx,80*25 ;Number of chars on screen
- sub cx,di ;Number from the cursor on
- mov al,' ' ;Fill with blanks
- rep stosb ;Fill screen
- pop es
- ret
- clreow endp
-
- ;=============================================================================
- ; Subroutine to clear the screen from the cursor to the end of the line
- ;=============================================================================
- clreol proc near
- mov cx,80 ;Number of cols across screen
- sub cl,dh ;Number from cursor on
- jle eol10 ;Jump if past end
- push es
- call scrloc ;Map DX to ES:DI
- mov al,' ' ;Fill end with blanks
- rep stosb ;Blank end of line
- pop es
- eol10: ret
- clreol endp
-
- ;=============================================================================
- ; Subroutine to insert a line at the row that the cursor is in.
- ;=============================================================================
- inslin proc near
- xor dh,dh ;Move to start of row
- cmp dl,24
- jae clreol ;Just clear bottom row
- push ds
- push es
- call scrloc ;Map DX to ES:DI
- mov ds,videobuf ;Set DS to video buffer
- mov cx,24*80 ;Number of chars on screen
- sub cx,di ;Number of chars past current row
- push di ;Save current row address
- mov di,25*80-1 ;Point to last char
- mov si,24*80-1 ;Point 1 line up
- std ;Auto decrement
- rep movsb ;Move lines down
- cld ;Auto increment
- mov cx,80 ;Number of chars on original line
- pop di ;Restore pointer to start of line
- mov al,' ' ;Fill with blanks
- rep stosb ;Blank line
- pop es
- pop ds
- ret
- inslin endp
-
- ;=============================================================================
- ; Subroutine to scroll the screen up over the current line
- ;=============================================================================
- dellin proc near
- xor dh,dh ;Move to start of row
- cmp dl,24
- jae clreol ;Just clear bottom row
- push ds
- push es
- call scrloc ;Map DX to ES:DI
- mov ds,videobuf ;Set DS to video buffer
- mov cx,24*80 ;First char of last row
- sub cx,di ;Number of chars past current row
- mov si,di
- add si,80 ;Source is one line down
- rep movsb ;Move chars up
- mov cx,80 ;Number of chars on last line
- mov al,' ' ;Fill with blanks
- rep stosb ;Blank line
- pop es
- pop ds
- ret
- dellin endp
-
- ;=============================================================================
- ; Subroutine to delete the current character by scrolling to the left
- ;=============================================================================
- delchr proc near
- push ds
- push es
- call scrloc ;Map dx to es:di
- mov ds,videobuf
- mov cx,79 ;Last char on line
- sub cl,dh
- jz dch20 ;Jump if on last char
- mov si,di
- inc si ;Source is 1 char to right
- rep movsb ;Move chars to left
- dch20: mov byte ptr [di],' '
- pop es
- pop ds
- ret
- delchr endp
-
- ;=============================================================================
- ; Subroutine to insert a character at the cursor position
- ;=============================================================================
- inschr proc near
- push ds
- push es
- mov cx,79 ;This is last col to move, +1 for length
- sub cl,dh ;Compute distance to end
- jle ichr20 ;Nothing to move...
- mov dh,78 ;This is address of last col to move
- call scrloc ;Compute pos
- mov ds,videobuf
- mov si,di
- inc di ;Destination is one byte over...
- std ;Remember to move us backwards
- rep movsb ;Move chars to right
- cld
- ichr20: pop es
- pop ds
- ret
- inschr endp
-
- ;=============================================================================
- ; Subroutine to turn off insert mode.
- ;=============================================================================
- noins proc near
- mov insmod,0 ;Turn off insert mode
- ret
- noins endp
-
- ;=============================================================================
- ; Subroutine to process ESC Y (The direct cursor addressing command)
- ;=============================================================================
- movcur proc near
- mov wcoord,0 ;Want two coordinates...
- mov ttstate,offset cstate
- ret
- movcur endp
-
- ;=============================================================================
- ; Subroutine to get a coordinate
- ;=============================================================================
- cstate proc near
- sub al,32 ;Coordinates offset by 32
- cmp wcoord,0 ;See if first coord already received
- jnz cs10 ;Jump if it was
- inc wcoord ;Indicate first was received
- mov savrow,al ;Save first coordinate (row)
- ret
- cs10: mov ttstate,offset nstate ;Reset state
- mov dh,al ;Put column in DH
- mov dl,savrow ;Get saved row
- jmp setcur ;Position cursor
- cstate endp
-
- ;=============================================================================
- ; Subroutine to enter insert mode.
- ;=============================================================================
- entins proc near
- mov insmod,0ffh ;enter insert mode...
- ret ;and return
- entins endp
-
- ;=============================================================================
- ; Subroutine to enter inverse video mode
- ;=============================================================================
- invvid proc near
- ret
- invvid endp
-
- ;=============================================================================
- ; Subroutine to exit inverse video mode
- ;=============================================================================
- nrmvid proc near
- ret
- nrmvid endp
-
- ;=============================================================================
- ; Subroutine to handle the set mode command. Sequence = ESC x (1,2,3,4,5...)
- ;=============================================================================
- setm proc near ;Here if ESC x entered
- mov ttstate,offset mstate ;Wait for value
- ret
- mstate: mov ttstate,offset nstate ;Put state back to normal
- cmp al,'4'
- jz uscurs ;Set underscore cursor
- push ax
- mov al,27 ;Output Esc character
- call pchar
- mov al,'x' ;Output set mode character
- call pchar
- pop ax ;Output unrecognized mode code
- jmp pchar
- setm endp
-
- ;=============================================================================
- ; Subroutine to handle the reset mode command. Sequence = ESC y (1,2,3,4,5...)
- ;=============================================================================
- resetm proc near ;Here if ESC y entered
- mov ttstate,offset rstate ;Wait for value
- ret
- rstate: mov ttstate,offset nstate ;Put state back to normal
- cmp al,'4'
- jz blcurs ;Set block cursor
- push ax
- mov al,27 ;Output Esc character
- call pchar
- mov al,'x' ;Output set mode character
- call pchar
- pop ax ;Output unrecognized mode code
- jmp pchar
- resetm endp
-
- ;=============================================================================
- ; Subroutine to set the underscore cursor
- ;=============================================================================
- uscurs proc near
- mov cx,4a0bh
- mov ah,1
- int 49h
- ret
- uscurs endp
-
- ;=============================================================================
- ; Subroutine to set a block cursor
- ;=============================================================================
- blcurs proc near
- mov cx,400bh
- mov ah,1
- int 49h
- ret
- blcurs endp
-
- ;=============================================================================
- ; save cursor in DX
- ;=============================================================================
- savecur proc near
- mov oldcur,dx
- ret
- savecur endp
-
- ;=============================================================================
- ; restore cursor onto screen
- ;=============================================================================
- restcur proc near
- mov dx,oldcur
- jmp setcur
- restcur endp
-
- ;=============================================================================
- ; Computes screen location to es:di, given col and row in dx.
- ; Trashes ax,bx
- ;=============================================================================
- scrloc proc near
- mov al,dl ;Get row
- xor ah,ah
- shl ax,1 ;Row * 2
- mov bx,ax
- shl ax,1 ;Row * 4
- shl ax,1 ;Row * 8
- add ax,bx ;Row * 10
- shl ax,1 ;Row * 20
- shl ax,1 ;Row * 40
- shl ax,1 ;Row * 80
- add al,dh
- adc ah,0
- mov di,ax
- mov es,videobuf
- ret
- scrloc endp
-
- ;=============================================================================
- ;
- ; 12-Dec-84 Joe Smith, CSM Computing Center, Golden CO 80401
- ;
- ; Description of Tektronix commands
- ;
- ; ESCAPE-CONTROL-E (ENQ) requests a status report
- ; ESCAPE-FORMFEED erases the screen.
- ; ESCAPE-CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
- ; ESCAPE-A-E enables the interactive plotter
- ; ESCAPE-A-F turns off the interactive plotter
- ; ESCAPE-M-L-2 Selects color 2 for drawing lines on 4113
- ; ESCAPE-M-T-: Selects color 10 for drawing text on 4113
- ; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
- ; CONTROL-UNDERLINE (US) turns off plot mode. (CR also works for all but 4025.)
- ; CONTROL-X switches HDSGVT from TEKTRONIX mode to NORMAL alpha mode.
- ;
- ; The plot commands are characters which specify the absolute position to move
- ; the beam. All moves except the one immediately after the GS character
- ; (Control-]) are with a visible trace.
- ;
- ; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
- ; altho only 0 to 780 are visible for Y due to screen geometry. The screen is
- ; 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
- ;
- ; For 4014-like devices - The positions are from 0 to 4096, but each movement
- ; is a multiple of 4 positions unless the high-resolution LSBXY are sent. This
- ; makes it compatible w/the 4010 in that a full sized plot fills the screen.
- ;
- ; HIX,HIY = High-order 5 bits of position
- ; LOX,LOY = Middle-order 5 bits of position
- ; LSBXY = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
- ;
- ; Hi Y Lo Y Hi X LSBXY Characters sent (Lo-X always sent)
- ; ---- ---- ---- ----- ----------------------------------
- ; Same Same Same Same Lo-X
- ; Same Same Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Same Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Same Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Same Diff Same Same Lo-Y, Lo-X
- ; Same Diff Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Diff Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Diff Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Same Same Same Hi-Y, Lo-X
- ; Diff Same Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Same Diff Same Hi-Y, Lo-Y, Hi-X, Lo-X
- ; Diff Same Diff Diff Hi-Y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Diff Same Same Hi-Y, Lo-Y, Lo-X
- ; Diff Diff Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Diff Diff Same Hi-y, Lo-Y, Hi-X, Lo-X
- ; Diff Diff Diff Diff Hi-y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Offset for byte: 40 140 140 40 100
- ;
- ; Note that LO-Y must be sent if HI-X has changed so the TEKTRONIX knows that
- ; the HI-X byte (in the range of 40-77 octal) is HI-X and not HI-Y. LO-Y must
- ; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
- ; accept LO-Y. The LSBXY byte is 140 + MARGIN*20 + LSBY*4 + LSBX. (MARGIN=0)
- ;
- ;============================================================================
-
- ;============================================================================
- ; Subroutine to initialize tektronix emulation. Called when GS char received
- ;============================================================================
- tekini proc near
- mov visible,0 ;Next move is invisible
- mov tekflag,1
- mov ttstate,offset xystate ;Go to ystate next
- ret
- tekini endp
-
- ;============================================================================
- ; Subroutine to clear the graphics screen. Called when a Form feed is received
- ;============================================================================
- ffeed proc near
- mov ah,14h ;Clear only graphics (not text)
- int 49h
- ret
- ffeed endp
-
- ;============================================================================
- ; Subroutine to clear the graphics and the text screen. Called if Esc FF rec.
- ;============================================================================
- escff proc near
- mov ah,13h ;Erase both text and graphics screen
- int 49h
- mov ah,14h
- int 49h
- mov ttstate,offset nstate
- ret
- escff endp
-
- ;=============================================================================
- ; Subroutine to send an identification code back. (Esc Z)
- ;=============================================================================
- sendid proc near
- mov al,esc
- call outport
- mov al,'\'
- call outport
- mov al,'K'
- call outport
- mov ttstate,offset nstate
- ret
- sendid endp
-
- ;=============================================================================
- ; Subroutine to turn on the crosshairs. (Esc ^Z)
- ;=============================================================================
- xhair proc near
- mov ttstate,offset nstate
- ret
- xhair endp
-
- ;=============================================================================
- ; Subroutine to extract the X,Y coordinates for Tektronix emulation.
- ; Expecting HIY because LOX was seen tekflag = 1
- ; Expecting HIX because LOY was seen tekflag = 0
- ; Written by Joe Smith, CSM
- ;=============================================================================
- xystate proc near
- cmp al,29 ;Process Pen up command
- jz tekini
- cmp al,13 ;Exit graphics mode on CR,LF,US
- je go2text
- cmp al,10
- je go2text
- cmp al,1fh
- je go2text
- cmp al,18h
- je go2text
- cmp al,20h ;Control char?
- jl tek20 ;Ignore it
- cmp al,40h
- jl tek30 ;20-3F are HIX or HIY
- cmp al,60h ;40-5F are LOX (causes beam movement)
- jl tek50 ;60-7F are LOY
-
- ;Extract low-order 5 bits of Y coordinate, set ESCFLAG=6
-
- mov ah,tek_loy ;Copy previous LOY to MSB (in case 4014)
- mov tek_lsb,ah
- and al,1Fh ;LOY is 5 bits
- mov tek_loy,al
- cmp tekflag,0 ;2nd LOY in a row?
- je tek20 ;Yes, then LSB is valid
- mov tek_lsb,0 ;1st one, clear LSB
- mov tekflag,0 ;LOY seen, expect HIX (instead of HIY)
- tek20: ret
-
- ;Extract high-order 5 bits (X or Y, depending on ESCFLAG)
-
- tek30: and ax,1Fh ;Just 5 bits
- mov cl,5
- shl ax,cl ;Shift over 5 bits
- cmp tekflag,1 ;Looking for HIY?
- jne tek40 ;No, HIX
- mov tek_hiy,ax ;Yes, this byte has HIY
- ret ;Keep ESCFLAG=4
- tek40: mov tek_hix,ax ;This byte has HIX (because ESCFLAG=6)
- mov tekflag,1 ;Reset to look for HIY next time
- ret
-
- ;Extract low-order X, do beam movement
-
- tek50: and al,1Fh ;Just 5 bits
- mov tek_lox,al
- mov ax,tek_hix ;Combine HIX*32
- or al,tek_lox ;with LOX
- mov bx,tek_hiy ;Same for Y
- or bl,tek_loy
- mov cl,visible ;0=move, 1=draw
- call tekdraw
- go2visi:mov visible,1 ;Next movement is with a visible trace
- mov tekflag,1 ;Reset to look for HIY next time
- ret
-
- go2text:mov ttstate,offset nstate
- ret
- xystate endp
-
- ;=============================================================================
- ;
- ; Routine to draw a line on the screen, using TEKTRONIX coordinates.
- ; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
- ; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
- ; Visiblity flag in CL, 0=move invisible, 1=draw a line.
- ;
- ; The TI-PRO has (719,299) as the coordinate of the lower-right corner.
- ; Calculate endpoint X=(9/13)*(HIX*32+LOX), Y=299-(5/13)*(HIY*32+LOY)
- ;
- ; The IBM-PC has (639,199) as the coordinate of the lower-right corner.
- ; Calculate endpoint X=(12/20)*(HIX*32+LOX), Y=199-(5/20)*(HIY*32+LOY)
- ;
- ;=============================================================================
- tekdraw proc near
- imul xmult ;Multiply by 9
- idiv xdiv ;Divide by 13
- push ax ;X is now between 0 and 708
- mov ax,bx
- imul ymult ;Multiply by 5
- idiv ydiv ;Divide by 13
- mov bx,ybot ;Y is now between 0 and 299
- sub bx,ax ;Put new Y in right reg
- pop ax ;Put new X in right reg
- or cl,cl
- jnz td10 ;Jump if line is visible
- mov oldx,ax ;Update last coordinates
- mov oldy,bx
- ret
- td10: mov si,oldx ;Previous position
- mov di,oldy
- mov oldx,ax ;Update position
- mov oldy,bx
- jmp line ;Plot line
- tekdraw endp
-
- ;=============================================================================
- ; LINE Subroutine to plot line with endpoints in BX,CX and SI,DI. The method
- ; used is an adaptation of octantal dynamic differential analyzer(DDA).
- ; SI,DI = Start X,Y coordinates. AX,BX = End X,Y coordinates.
- ;
- ;=============================================================================
- line proc near
- cmp ax,si ;Compare X1 to X2
- jl plusx ;Jump if X1 is to left of X2
- xchg ax,si ;Swap points so point 1 is to left
- xchg bx,di ; This mirrors quadrants 2,3 to 1,4
- plusx: sub si,ax ;Get delta X into SI
- sub di,bx ;Get delta Y into DI
-
- ; Left-hand coordinate in (AX,BX), delta movement in (SI,DI)
- ; Map X1,Y1 in AX,BX to offset into the video buffer in BX and bit pos in AX
-
- shl bx,1 ;2*Y
- shl bx,1 ;4*Y
- mov bp,bx ;Save 4*Y
- shl bx,1 ;8*Y
- shl bx,1 ;16*Y
- shl bx,1 ;32*Y
- add bp,bx ;DX = 36*Y
- shl bx,1 ;64*Y
- shl bx,1 ;128*Y
- sub bx,bp ;128Y - 36Y = 92*Y
- mov cl,al ;Low 4 bits of X position
- and cl,0Fh
- shr ax,1 ;Divide by 8 bits per byte
- shr ax,1
- shr ax,1
- and ax,0fffeh ;Truncate down to word boundary
- add bx,ax
- mov ax,8000h ;Start with set bit on left edge
- shr ax,cl ;Shift it over the correct amount
-
- ;AX has bit in position, BX has word address, SI has delta-X, DI has delta-Y
-
- mov bp,92 ;Offset from 1 pixel to one below it
- or di,di ;See if delta y is below zero
- jg line10 ;Yes, already on quadrant 3
- neg di ;Get absolute value of delta y
- neg bp ;Move toward top of screen
- line10: push ds
- mov ds,grseg
- cmp di,si ;Compare delta-Y with delta-X
- jg line30 ;Greater than +/- 45 degrees
-
- ; Here when slope is less than +/- 45 degrees
-
- line20: mov cx,si ;Number of pixels to plot = delta x
- inc cx ; + 1
- mov dx,si ;Initialize line error to -(deltax)/2
- shr dx,1 ;
- neg dx ;
- line2a: or [bx],ax ;Turn on pixel pointed to by BX and Al
- ror ax,1 ;Increment X direction
- jnc line2b ;
- add bx,2 ;
- line2b: add dx,di ;Add delta y to line error
- jl line2c ;Jump for next pixel if error < 0
- add bx,bp ;Go up (or down) one pixel
- sub dx,si ;Subtract delta x from line error
- line2c: loop line2a ;Set next pixel
- pop ds
- ret
-
- ; Here when slope is greater than +/- 45 degrees
-
- line30: mov cx,di ;Number of pixels to plot = delta y
- inc cx ; + 1 (Delta Y was negated above)
- mov dx,di ;Initialize line error to -(deltay)/2
- shr dx,1 ;
- neg dx ;
- line3a: or [bx],ax ;Turn on pixel pointed to by BX and Al
- add bx,bp ;Move up (or down) 1 pixel
- add dx,si ;Add delta x to line error
- jl line3c ;Jump for next pixel if error < 0
- ror ax,1 ;Time to increment X direction
- jnc line3b ;
- add bx,2 ;
- line3b: sub dx,di ;Subtract delta y from line error
- line3c: loop line3a ;Set next pixel
- pop ds
- ret
- line endp
-
- code ends
- end
-